package com.qianxun.watchdog;

import com.qianxun.watchdog.communication.MessageHandler;
import com.qianxun.watchdog.script.ScriptExecutor;

import java.util.*;

/**
 * @author: huwei
 * @date: 2020/10/19 14:00
 * @version: 1.0.0
 */
public class Watchdog {

    private Set<Master> masterSet = new HashSet<>();

    private Map<String ,Integer> restartMap = new HashMap<>(16);

    private MessageHandler messageHandler = master -> {
        Watchdog.this.masterSet.add(master);
        System.out.println("add new task:" + master.toString());
        System.out.println("task :" + masterSet);
    };

    public Watchdog(){
        new Thread(()-> watch()).start();
    }

    private void watch(){
        while(true){
            if(this.masterSet.isEmpty()){
                System.out.println("master is empty,ready to sleep 60s");
                try {
                    Thread.sleep(60 * 1000);
                }catch (Exception e){}
            }

            if(!this.masterSet.isEmpty()){
                List<Master> lose = new ArrayList<>();

                this.masterSet.forEach(master -> {
                    byte[] bytes;
                    try {
                        String script = "ps -ef | grep "+master.getName()+" | grep -v grep | head -n 1 | awk '{print $2}'";
                        bytes = ScriptExecutor.getInstance().run(script);
                    } catch (Exception e) {
                        System.out.println("status script execute error： " + "ps -ef | grep "+master.getName()+" | grep -v grep | head -n 1 | awk '{print $2}'");
                        return;
                    }
                    if(bytes != null ){
                        try{
                            Integer.parseInt(new String(bytes).trim());
                            this.restartMap.remove(master.getName());
                            return;
                        }catch (Exception e){
                        }
                    }

                    Integer count = this.restartMap.get(master.getName());
                    count = count == null ? 1 : ++count;

                    if(count > 100){
                        lose.add(master);
                        this.restartMap.remove(master.getName());
                        System.out.println(master.getName() + " restart error ,and removed");
                    }else{
                        this.restartMap.put(master.getName() ,count);
                        try {
                            byte[] res = ScriptExecutor.getInstance().run(restartScript(master));
                            System.out.println("restart " + master.getName() + " ,result：" + new String(res ,"gb2312"));
                        } catch (Exception e) {
                            System.out.println("status script execute error： " + restartScript(master));
                        }
                    }
                });

                lose.forEach(master -> {
                    this.masterSet.remove(master);
                });
            }

            int sleep = this.restartMap.isEmpty() ? 60 * 1000 : 10 * 1000;
            try {
                Thread.sleep(sleep);
            }catch (Exception e){
            }
        }
    }

    public MessageHandler getMessageHandler() {
        return messageHandler;
    }

    private String restartScript(Master master){
        String console = master.getPath().replace(master.getName() ,"console.log");
        return "nohup java -jar " + master.getPath() + " > "+console+" & \n";
    }
}
